package com.syncomponents.spi.http;

import java.io.IOException;
import java.util.concurrent.Callable;

import javax.annotation.Resource;

import org.apache.commons.codec.binary.Base64;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.syncomponents.context.SynFactory;
import com.syncomponents.context.support.HandlerType;
import com.syncomponents.context.support.MessageHandler;
import com.syncomponents.core.EnumAck;
import com.syncomponents.core.ServiceException;
import com.syncomponents.util.MessageUtil;
import commonj.sdo.DataObject;
import commonj.sdo.helper.XMLDocument;
import commonj.sdo.helper.XMLHelper;

/**
 * 消息服务统一http接口， 传入xml格式消息体，只支持POST方法
 * 
 * @author sunkey
 * @date Mar 13, 2014
 */
@Controller
@RequestMapping("/api/service/message")
public class MessageController {

    private final Logger logger = LoggerFactory.getLogger(getClass());

    @Resource
    private SynFactory<MessageHandler> handlerFactory;

    @RequestMapping(value = "/doProcessing", method = RequestMethod.POST, headers = "Accept=text/plain")
    @ResponseBody
    public Object doProcessing(@RequestBody String msgBody) {

        if (logger.isDebugEnabled()) {
            logger.debug("message is {}", msgBody);
        }

        Object response = null;
        try {
            MessageHandler messageHandler = handlerFactory.getBean(HandlerType.identifyHanderType(msgBody).getValue());
            if (messageHandler == null) {
                throw new ServiceException("The message format is not supported");
            }
            response = messageHandler.handle(msgBody);
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            response = MessageUtil.getErrorResponseMessage(msgBody, e.getMessage());
        }

        return response;
    }

    @RequestMapping(value = "/getLabels", method = RequestMethod.POST, produces = "application/pdf")
    @ResponseBody
    public byte[] getLabels(@RequestBody String msgBody) throws IOException {

        if (logger.isDebugEnabled()) {
            logger.debug("message is {}", msgBody);
        }
        MessageHandler messageHandler = handlerFactory.getBean(HandlerType.identifyHanderType(msgBody).getValue());
        if (messageHandler == null) {
            throw new ServiceException("The message format is not supported");
        }
        Object response = messageHandler.handle(msgBody);
        XMLDocument resultDocument = XMLHelper.INSTANCE.load(response.toString());
        DataObject result = resultDocument.getRootObject();
        byte[] content = Base64.decodeBase64(result.getString("content"));

        if (!EnumAck.Success.getValue().equals(result.getString("ack").trim())) {
            throw new ServiceException(result.getString("message"));
        }
        return content;
    }

    @RequestMapping(value = "/testAsyn")
    @ResponseBody
    @Deprecated
    public Callable<String> doProcessingAsyn() {

        return new Callable<String>() {
            public String call() throws Exception {
                // Object response = messageHandler.handle(msgBody);

                // return (byte[])response;
                return "test asyn";
            }
        };

    }

    @RequestMapping("/doProcessingAsyn")
    @ResponseBody
    @Deprecated
    public Callable<Object> doProcessing(final String action, final String msgType, String params) {

        return new Callable<Object>() {
            @Override
            public Object call() throws Exception {
                return "";
            }
        };
    }

}
